#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   utils.py    
@Contact :   raogx.vip@hotmail.com
@License :   (C)Copyright 2020

@Modify Time      @Author    @Version    @Desciption
------------      -------    --------    -----------
2020-11-10 16:53   WandongShi      1.0         None
'''
import random
import torch
from torch.autograd import Variable


def overleap_check(span1, span2):
    # 判断两个span是否有重叠
    st1 = span1[0]
    st2 = span2[0]
    ed1 = span1[1]
    ed2 = span2[1]
    if ((st1 >= st2) and (st1 < ed2)) or ((st2 >= st1) and (st2 < ed1)):
        return False
    if ((ed1 > st2) and (ed1 <= ed2)) or ((ed2 > st1) and (ed2 <= ed1)):
        return False
    return True

"""Spliting the corpus with batch_size"""
def makeBatch(data, batch_size):
    batch_data = []
    random.shuffle(data)
    batch_num = int(len(data) / batch_size)
    print("batch_size is:", batch_size)
    print("batch_num is:", batch_num)
    for i in range(batch_num):
        batch_data.append(data[i * batch_size:(i + 1) * batch_size])
    if len(data) % batch_size != 0:
        batch_data.append(data[(i + 1) * batch_size:])
    return batch_data

"""Enumerating all the spans in a sentence"""
def make_span_candidates(l):
    candidates = []
    for i in range(l):
        for j in range(i, l):
            candidates.append([i, j])
    return candidates

cuda_num = 1
def to_var(x, volatile=False):
    if torch.cuda.is_available():
        x = x.cuda(cuda_num)
    return Variable(x, volatile=volatile)

def get_eva(outputs, labels):
    """Computing the accuracy in the training process"""
    _, predict = torch.max(outputs.data, 1)
    predict_list = predict.cpu().numpy().tolist()
    labels_list = labels.cpu().numpy().tolist()
    op_related = 0;
    op_corrected = 0;
    op_predicted = 0;

    as_related = 0;
    as_corrected = 0;
    as_predicted = 0;

    for idx, val in enumerate(predict_list):
        # print(val)
        if(val == 1 and labels_list[idx] == 1):
            op_corrected += 1
            op_related += 1
            op_predicted += 1
        elif(val == 1):
            op_predicted += 1
        elif(labels_list[idx] == 1):
            op_related += 1

        if(val == 2 and labels_list[idx] == 2):
            as_corrected += 1
            as_related += 1
            as_predicted += 1
        elif (val == 2):
            as_predicted += 1
        elif (labels_list[idx] == 2):
            as_related += 1


    return op_related, op_corrected, op_predicted, as_related, as_corrected, as_predicted

def span_candidates_filter(candidates, max_len):
    new_candidates = []
    for candidate in candidates:
        if candidate[1] - candidate[0] + 1 <= max_len:
            new_candidates.append(candidate)
    return new_candidates

def span_filter_triplet(max_len, triplet_arr):
    triplet_candidates = []
    for triplet in triplet_arr:
        for ele in triplet:
            for i in range(ele[0], ele[1]+1):
                for j in range(i, ele[1]+1):
                    triplet_candidates.append([i, j])
    new_candidates = []
    for candidate in triplet_candidates:
        if candidate[1] - candidate[0] + 1 <= max_len:
            new_candidates.append(candidate)
    return new_candidates